/*
 * Copyright (c) 2021
 * User:魔金多商户商城
 * File:AuthorityInterceptor.java
 * Date:2020/11/27 16:26:27
 */

package com.ruoyi.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.appletsutil.ResultCode;
import com.ruoyi.appletsutil.UnAuthorizedException;
import com.ruoyi.common.annotation.UnAuth;
import com.ruoyi.common.constant.Rediskey;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.tc.domain.TcMember;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * Created by 魔金商城 on 2018/6/13.
 * 访问拦截器
 */
@Slf4j
@Component
public class AuthorityInterceptor extends HandlerInterceptorAdapter {

    /**
     * 注入redis服务
     */
    @Autowired
    private RedisCache redisService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestType = ((HttpServletRequest) request).getMethod();
        String fullUrl = ((HttpServletRequest) request).getRequestURL().toString();
        log.info("preHandle :" + fullUrl);
        // 如果不需要拦截 则直接返回
        if (!isNeedFilter(handler)) {
            log.info("isnot NeedFilter:" + fullUrl);
            return true;
        }
        if (fullUrl.contains("koTime") || fullUrl.contains("error")) {
            return true;
        }
        // 认证信息在header 中的key
        final String authHeader = request.getHeader("Authorization");
        log.debug("need  authHeader....." + authHeader + "==" + fullUrl);
        if (Objects.isNull(authHeader) || !authHeader.startsWith("Bearer") || authHeader.length() < 10) {
            log.info("AuthorityInterceptor preHandle fail....{}", fullUrl);
            throw new UnAuthorizedException("401", ResultCode.NOT_AUTHORIZED);
        }
        // 获得凭证
        TcMember claims = getAppletsClaimsFromRedis(authHeader.substring(7));

        // 没有凭证 直接返回
        if (Objects.isNull(claims)) {
            log.info("AuthorityInterceptor preHandle fail....{}", fullUrl);
            throw new UnAuthorizedException("401", ResultCode.NOT_AUTHORIZED);
        }
        // 校验有没有uid  如果没有uid  则直接返回
        if (claims.getId() < 1) {
            log.error("applets has not authorized:{}", fullUrl);
            throw new UnAuthorizedException("401", ResultCode.NOT_AUTHORIZED);
        }


        request.setAttribute("claims", claims);

        return true;
    }

    private String formMapKey(Object userId, String mothedName, String requestType,
                              String ip, String params, String token) {
        return "\"time\"" + ":\"" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date())
                + "\",\"name\"" + ":\"" + mothedName + "\",\"uid\":\"" + userId
                + "\",\"type\":\"" + requestType + "\",\"ip\":\"" + ip
                + "\",\"token\":\"" + token + "\",\"params\":\"" + params + "\"";
    }

    /**
     * 根据token从redis 获取uid和customerId
     *
     * @param token token
     * @return 返回uid和customerId
     */
    private TcMember getAppletsClaimsFromRedis(String token) {
        String claims = redisService.getValue(String.format(Rediskey.TOKEN, token));
        return StringUtils.isEmpty(claims) ? null : JSONObject.parseObject(claims, TcMember.class);
    }


    /**
     * 判断是否需要拦截
     */
    private boolean isNeedFilter(Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            return handlerMethod.getMethod().getAnnotation(UnAuth.class) == null;
        }
        return false;
    }

}
